package com.zzyl.nursing.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huaweicloud.sdk.iotda.v5.IoTDAClient;
import com.huaweicloud.sdk.iotda.v5.model.ListProductsRequest;
import com.huaweicloud.sdk.iotda.v5.model.ListProductsResponse;
import com.huaweicloud.sdk.iotda.v5.model.ProductSummary;
import com.zzyl.common.constant.CacheConstants;
import com.zzyl.common.dto.DeviceDto;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.huaweiyun.HuaweiIotUtil;
import com.zzyl.common.utils.uuid.UUID;
import com.zzyl.nursing.domain.Device;
import com.zzyl.nursing.mapper.DeviceMapper;
import com.zzyl.nursing.service.IDeviceService;
import com.zzyl.nursing.vo.ProductVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * 产品设备Service业务层处理
 *
 * @author ruoyi
 * @date 2025-02-28
 */
@Service
public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> implements IDeviceService {
    @Autowired
    private DeviceMapper deviceMapper;

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private IoTDAClient client;

    @Autowired
    private HuaweiIotUtil huaweiIotUtil;


    @Override
    public void ductList() {
        ListProductsRequest request = new ListProductsRequest();
        request.setLimit(50);

        ListProductsResponse listProductsResponse = client.listProducts(request);
        if (listProductsResponse.getHttpStatusCode() != 200) {
            throw new BaseException("获取产品列表失败");
        }

        List<ProductSummary> products = listProductsResponse.getProducts();
        List<ProductVo> productVos1 = BeanUtil.copyToList(products, ProductVo.class);
        redisTemplate.opsForValue().set(CacheConstants.IOT_ALL_PRODUCT_KEY, productVos1);
    }

    @Override
    public List<ProductVo> allProduct() {
        //从redis中查询数据
        List<ProductVo> jsonStr=(List<ProductVo>)redisTemplate.opsForValue().get(CacheConstants.IOT_ALL_PRODUCT_KEY);

        return jsonStr;
    }

    @Override
    public List<Device> selectDeviceList(Device device) {
        return deviceMapper.selectDeviceList(device);
    }

    @Override
    public void saveRegister(DeviceDto deviceDto) {
        this.validDeviceBefore(deviceDto);


        String s = UUID.randomUUID().toString().replaceAll("-", "");
        deviceDto.setSecret(s);
        String device = huaweiIotUtil.addDevice(deviceDto);

        Device bean = BeanUtil.toBean(deviceDto, Device.class);
        if (Objects.isNull(bean.getLocationType())){
            bean.setLocationType(-1);
        }
        // 华为设备id 绑定至 中州养老业务数据库
        deviceDto.setIotId(device);
        // 设置秘钥
        deviceDto.setSecret(s);

        try {
             this.save(bean);
        } catch (Exception e) {
            this.huaweiIotUtil.removeDevice(device);
            throw new RuntimeException("新增失败");
        }


    }

    private void validDeviceBefore(DeviceDto deviceDto) {
        // 1、判断设备名称是否重复
        LambdaQueryWrapper<Device> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Device::getDeviceName, deviceDto.getDeviceName());
        if (count(queryWrapper) > 0) {
            throw new BaseException("设备名称已存在，请重新输入");
        }

        // 2、检验设备标识码是否重复
        LambdaQueryWrapper<Device> queryWrapperNodeId = new LambdaQueryWrapper<>();
        queryWrapperNodeId.eq(Device::getNodeId, deviceDto.getNodeId());
        if (count(queryWrapperNodeId) > 0) {
            throw new BaseException("设备标识码已存在，请重新输入");
        }

        // 3、校验同一位置是否绑定了同一类型的产品
        LambdaQueryWrapper<Device> condition = new LambdaQueryWrapper<>();
        condition.eq(Device::getProductKey, deviceDto.getProductKey())
                .eq(Device::getLocationType, deviceDto.getLocationType())
                .eq(Device::getPhysicalLocationType, deviceDto.getPhysicalLocationType())
                .eq(Device::getBindingLocation, deviceDto.getBindingLocation());
        if (count(condition) > 0) {
            throw new BaseException("该老人/位置已绑定该产品，请重新选择");
        }
    }
}
